package com.cjd.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.LinearInterpolator;
import android.widget.Scroller;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.cjd.common.holder.SwipeRecyclerHolder;
import com.cjd.common.utils.LogUtils;

/**
 * @Author chenjidong
 * @email 374122600@qq.com
 * created 2019/10/5
 * description 左滑显示删除view  只支持 LinearLayoutManager
 */
public class SwipeRecyclerView extends RecyclerView {
    private static final String TAG = SwipeRecyclerView.class.getSimpleName();
    private int mTouchSlop;
    private int xDown, yDown, xMove, yMove;
    /**
     * 当前选中的item索引
     */
    private int currentSelectPosition;
    private Scroller mScroller;

    private View mCurrentItemLayout, mLastItemLayout;
    private View mRightHidden;//隐藏部分

    /**
     * 隐藏部分长度
     */
    private int mHiddenWidth;
    /**
     * 记录连续移动的长度
     */
    private int mMoveWidth = 0;
    /**
     * 是否是第一次touch
     */
    private boolean isFirst = true;


    /**
     * 删除的监听事件
     */
    private OnRightClickListener mRightListener;

    public void setRightClickListener(OnRightClickListener listener) {
        this.mRightListener = listener;
    }


    public SwipeRecyclerView(Context context) {
        this(context, null);
        init(context);

    }

    public SwipeRecyclerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        init(context);

    }

    public SwipeRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);

    }

    private void init(Context context) {
        //滑动到最小距离
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();

        //初始化Scroller
        mScroller = new Scroller(context, new LinearInterpolator(context, null));
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent e) {
        int x = (int) e.getX();
        int y = (int) e.getY();
        switch (e.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //记录当前按下的坐标
                xDown = x;
                yDown = y;
                //计算选中哪个Item
                int firstPosition = ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition();
                Rect itemRect = new Rect();

                final int count = getChildCount();
                for (int i = 0; i < count; i++) {
                    final View child = getChildAt(i);
                    if (child.getVisibility() == View.VISIBLE) {
                        child.getHitRect(itemRect);
                        if (itemRect.contains(x, y)) {
                            currentSelectPosition = firstPosition + i;
                            break;
                        }
                    }
                }

                if (isFirst) {//第一次时，不用重置上一次的Item
                    isFirst = false;
                } else {
                    //屏幕再次接收到点击时，恢复上一次Item的状态
                    if (mLastItemLayout != null && mMoveWidth > 0) {
                        //将Item右移，恢复原位
                        scrollRight(mLastItemLayout, (0 - mMoveWidth));
                        //清空变量
                        mHiddenWidth = 0;
                        mMoveWidth = 0;
                    }

                }

                //取到当前选中的Item，赋给mCurrentItemLayout，以便对其进行左移
                View item = getChildAt(currentSelectPosition - firstPosition);
                if (item != null) {
                    if (getChildViewHolder(item) instanceof SwipeRecyclerHolder) {
                        //获取当前选中的Item
                        SwipeRecyclerHolder viewHolder = (SwipeRecyclerHolder) getChildViewHolder(item);
                        if (viewHolder.mRightItem == null)
                            throw new RuntimeException("SwipeRecyclerHolder.class 未设置 指定删除view");

                        mCurrentItemLayout = viewHolder.itemView;
                        mRightHidden = viewHolder.mRightItem;
                        mRightHidden.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                if (mRightListener != null) {
                                    //删除
                                    mRightListener.onRightClick(currentSelectPosition, "");
                                }
                            }
                        });

                        //这里将删除按钮的宽度设为可以移动的距离
                        mHiddenWidth = mRightHidden.getWidth();
                    }
                }
                break;

            case MotionEvent.ACTION_MOVE:
                xMove = x;
                yMove = y;
                int dx = xMove - xDown;//为负时：手指向左滑动；为正时：手指向右滑动。这与Android的屏幕坐标定义有关
                int dy = yMove - yDown;//

                //左滑
                if (dx < 0 && Math.abs(dx) > mTouchSlop && Math.abs(dy) < mTouchSlop) {
                    int newScrollX = Math.abs(dx);
                    if (mMoveWidth >= mHiddenWidth) {//超过了，不能再移动了
                        newScrollX = 0;
                    } else if (mMoveWidth + newScrollX > mHiddenWidth) {//这次要超了，
                        newScrollX = mHiddenWidth - mMoveWidth;
                    }
                    //左滑，每次滑动手指移动的距离
                    scrollLeft(mCurrentItemLayout, newScrollX);
                    //对移动的距离叠加
                    mMoveWidth = mMoveWidth + newScrollX;
                } else if (dx > 0) {//右滑
                    //执行右滑，这里没有做跟随，瞬间恢复
                    scrollRight(mCurrentItemLayout, 0 - mMoveWidth);
                    mMoveWidth = 0;
                }

                break;
            case MotionEvent.ACTION_UP://手抬起时
                if (mCurrentItemLayout != null) {
                    int scrollX = mCurrentItemLayout.getScrollX();

                    if (mHiddenWidth > mMoveWidth) {
                        int toX = (mHiddenWidth - mMoveWidth);
                        if (scrollX > mHiddenWidth / 2) {//超过一半长度时松开，则自动滑到左侧
                            scrollLeft(mCurrentItemLayout, toX);
                            mMoveWidth = mHiddenWidth;
                        } else {//不到一半时松开，则恢复原状
                            scrollRight(mCurrentItemLayout, 0 - mMoveWidth);
                            mMoveWidth = 0;
                        }
                    }
                    mLastItemLayout = mCurrentItemLayout;
                }
                break;


        }
        return super.onTouchEvent(e);
    }


    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {

            LogUtils.e("computeScroll getCurrX ->" + mScroller.getCurrX());
            mCurrentItemLayout.scrollBy(mScroller.getCurrX(), 0);
            invalidate();
        }
    }

    /**
     * 向左滑动
     */
    private void scrollLeft(View item, int scrollX) {
        LogUtils.e(" scroll left -> " + scrollX);
        if (item != null)
            item.scrollBy(scrollX, 0);
    }

    /**
     * 向右滑动
     */
    private void scrollRight(View item, int scrollX) {
        LogUtils.e(" scroll right -> " + scrollX);
        if (item != null)
            item.scrollBy(scrollX, 0);
    }

    public interface OnRightClickListener {
        void onRightClick(int position, String id);
    }
}
